﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using Miris.HumanMilkAnalyser.Service.Interface;
using Miris.HumanMilkAnalyser.WPF.Model;

namespace Miris.HumanMilkAnalyser.WPF.Shared
{
    public abstract class MyViewModelBase : ViewModelBase, IDisposable
    {
        public const string RequestDisplayErrorMessageToken = "RequestDisplayErrorMessage";
        public const string RequestClearErrorMessageToken = "RequestClearErrorMessage";
        public const string RequestDisplayMessageToken = "RequestDisplayMessage";
        public const string RequestClearMessageToken = "RequestClearMessage";
        public const string RequestShowMessageBoxMessageToken = "RequestShowMessageBoxMessage";
        public const string RequestGotoPageMessageToken = "RequestGotoPageMessage";
        public const string RequestRestartCurrentApplicationMessageToken = "RequestRestartCurrentApplicationMessage";
        protected IServiceFactory ServiceFactory;
        protected IDataService CurrentDataService;
        protected bool IsCleanup;

        public MyViewModelBase(IDataService dataService)
        {
            CurrentDataService = dataService;

            if (CurrentDataService != null)
            {
                CurrentDataService.GetServiceFactory(
                    (item, error) =>
                    {
                        if (error != null)
                        {
                            // Report error here
                            return;
                        }

                        ServiceFactory = item;
                    });
            }

            IsCleanup = false;
            RegisterMessages();
        }

        /// <summary>
        /// Request SummaryMessageDisplayViewModel to display a provided error message.
        /// </summary>
        /// <param name="errorMessage">Provided error message.</param>
        public static void RequestDisplayErrorMessage(string errorMessage)
        {
            Messenger.Default.Send<string>(errorMessage, RequestDisplayErrorMessageToken);
        }

        /// <summary>
        /// Request SummaryMessageDisplayViewModel to clear error message.
        /// </summary>
        public static void RequestClearErrorMessage()
        {
            Messenger.Default.Send<string>(string.Empty, RequestClearErrorMessageToken);
        }

        /// <summary>
        /// Request SummaryMessageDisplayViewModel to display a provided message.
        /// </summary>
        /// <param name="message">Provided message.</param>
        public static void RequestDisplayMessage(string message)
        {
            Messenger.Default.Send<string>(message, RequestDisplayMessageToken);
        }

        /// <summary>
        /// Request SummaryMessageDisplayViewModel to clear message.
        /// </summary>
        public static void RequestClearMessage()
        {
            Messenger.Default.Send<string>(string.Empty, RequestClearMessageToken);
        }

        /// <summary>
        /// Reset the necessary properties for binding.
        /// </summary>
        public virtual void ResetProperties()
        {
            RequestClearErrorMessage();
            RequestClearMessage();
        }

        /// <summary>
        /// Since the ViewModel is static instance which gotten by ServiceLocator.Current.GetInstance.
        /// When we open the View again, the Constructor will not be called again.
        /// This method makes sure all necessary messages will be registered again.
        /// </summary>
        public virtual void CheckRegisterMessages()
        {
            // Only register all messages after cleanup is done. Otherwize it will cause duplicate register.
            if (IsCleanup)
            {
                RegisterMessages();
            }
        }

        public virtual void Dispose()
        {
            Cleanup();
        }

        /// <summary>
        /// Perform necessary Cleanup.
        /// All registered messages will be unregistered.
        /// </summary>
        public override void Cleanup()
        {
            base.Cleanup();
            IsCleanup = true;
        }

        /// <summary>
        /// Register all necessary messages.
        /// </summary>
        protected virtual void RegisterMessages() { }

        /// <summary>
        /// Send RequestShowMessageBoxMessage to WindowBase.
        /// </summary>
        /// <param name="message">The input message which will be poped up.</param>
        protected virtual void RequestShowMessageBox(string message)
        {
            Messenger.Default.Send<string>(message, RequestShowMessageBoxMessageToken);
        }

        protected virtual void RequestGotoPage(PageBase page)
        {
            // Send RequestGotoPageMessage to PageBase.
            Messenger.Default.Send<PageBase>(page, RequestGotoPageMessageToken);
        }
    }
}
